package com.ea.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.ea.common.constant.BaseNumConstant;
import com.ea.common.enums.DeliverStatusEnums;
import com.ea.common.enums.OperationResultCode;
import com.ea.common.enums.OrderStatusEnums;
import com.ea.common.exception.ServiceException;
import com.ea.common.response.JsonResult;
import com.ea.domain.dto.OrderManageUpdateDTO;
import com.ea.domain.dto.UpdateMemoDTO;
import com.ea.domain.entity.LogisticInfo;
import com.ea.domain.entity.OrderFormDetail;
import com.ea.domain.entity.OrderFormInfo;
import com.ea.domain.query.OrderManageQueryDTO;
import com.ea.domain.vo.OrderManageVO;
import com.ea.holder.AdminHolderInfo;
import com.ea.mapper.LogisticInfoMapper;
import com.ea.mapper.OrderFormDetailMapper;
import com.ea.mapper.OrderFormInfoMapper;
import com.ea.service.ILogisticInfoService;
import com.ea.service.IOrderLogService;
import com.ea.service.IOrderManageInfoService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author NAME-L
 * @Description TODO
 * @className IOrderFormInfoServiceImpl
 * @date 2022-12-14 00:25:55
 */
@Service
public class IOrderManageInfoServiceImpl implements IOrderManageInfoService {

    private static final Logger logger = LoggerFactory.getLogger(IOrderManageInfoServiceImpl.class);
    @Autowired
    private OrderFormInfoMapper infoMapper;

    @Autowired
    private OrderFormDetailMapper detailMapper;

    @Autowired
    private IOrderLogService logService;

    @Autowired
    private LogisticInfoMapper logisticInfoMapper;

    @Autowired
    private ILogisticInfoService logisticInfoService;


    @Override
    public PageInfo<OrderManageVO> selectListByCondition(OrderManageQueryDTO orderQuery) {
        logger.info("查询订单信息，query:{}", JSON.toJSONString(orderQuery));
        Integer pageIndex = orderQuery.getPageIndex() == null ? BaseNumConstant.NUM_1 : orderQuery.getPageIndex();
        Integer pageSize = orderQuery.getPageSize() == null ? BaseNumConstant.NUM_20 : orderQuery.getPageSize();
        PageHelper.startPage(pageIndex, pageSize);
        List<OrderManageVO> orderInfoDTOList = infoMapper.selectAllByCondition(orderQuery);
        return new PageInfo<>(orderInfoDTOList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderInfo(OrderManageUpdateDTO updateDTO) {
        OrderFormInfo orderInfo = infoMapper.selectOneByOrderId(updateDTO.getOrderId());
        // 只有已经确认的订单才可以修改发货单信息
        OrderFormInfo updateInfo = new OrderFormInfo();
        BeanUtil.copyProperties(updateDTO, updateInfo);
        StringBuilder builder = new StringBuilder();
        if (!OrderStatusEnums.CONFIRM.getCode().equals(orderInfo.getOrderStatus())) {
            logService.insertOrderLog(String.format("更新订单信息失败，订单状态为：“%s”", OrderStatusEnums.getOrderStatus(orderInfo.getOrderStatus())), orderInfo, AdminHolderInfo.getAdminName());
            logger.warn("更新订单信息失败，订单状态为非 “已确认” 状态");
            throw new ServiceException(OperationResultCode.ORDER_STATUS_FORBID.getCode(),
                    String.format(OperationResultCode.ORDER_STATUS_FORBID.getMsg(), orderInfo.getOrderId(), OrderStatusEnums.getOrderStatus(orderInfo.getOrderStatus())));

        }
        if (updateDTO.getReceiveName() != null) {
            builder.append("收件人姓名由：").append(orderInfo.getReceiveName()).append(" 变更为：").append(updateInfo.getReceiveName());
        }
        if (updateDTO.getPhone() != null) {
            builder.append("联系方式由：").append(orderInfo.getPhone()).append(" 变更为：").append(updateInfo.getPhone());
        }

        LogisticInfo updateLogisticInfo = new LogisticInfo();
        // 是否需要重新生成物流单信息
        // 如果修改了订单的地址那么需要判断该订单是否发货，如果发货那么就要驳回已发货的物流单之后后，重新生成物流单，重新发货
        boolean changeAddress = false;
        if (StringUtils.isNotEmpty(updateDTO.getAddress())) {
            // 如果是以发货状态，则需要从当前地址发货至新地址
            LogisticInfo logisticInfo = logisticInfoMapper.selectOneByLogisticId(orderInfo.getLogisticId());
            // 如果地址不一致，那么就更新物流单发货信息
            if (!logisticInfo.getDestination().equals(updateDTO.getAddress())) {
                changeAddress = true;
                logisticInfoMapper.deleteLogisticInfo(logisticInfo.getLogisticId());
                builder.append("地址由：").append(orderInfo.getProvince()).append(orderInfo.getCity()).append(orderInfo.getDistrict()).append(orderInfo.getAddress());
                builder.append("变更为：").append(updateInfo.getProvince()).append(updateInfo.getCity()).append(updateInfo.getDistrict()).append(updateInfo.getAddress());
            } else {
                updateLogisticInfo.setOrderId(orderInfo.getOrderId());
                updateLogisticInfo.setConsigneeName(updateDTO.getReceiveName());
                updateLogisticInfo.setConsigneePhone(updateDTO.getPhone());
                updateLogisticInfo.setLogisticId(logisticInfo.getLogisticId());
            }
        }
        infoMapper.updateOrderInfo(updateDTO);
        if (changeAddress) {
            logisticInfoService.createLogisticInfoBatch(Collections.singletonList(updateDTO.getOrderId()));
        } else {
            logisticInfoMapper.updateLogisticInfo(updateLogisticInfo);
        }
        logService.insertOrderLog(builder.toString(), updateInfo, AdminHolderInfo.getAdminName());
        // 调用物流单生成轨迹方法
        // 更新进订单表
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOrderInfoMemo(UpdateMemoDTO memoDTO) {
        OrderFormInfo orderInfo = infoMapper.selectOneByOrderId(memoDTO.getOrderId());
        if (!OrderStatusEnums.CANCLE.getCode().equals(orderInfo.getOrderStatus()) || !OrderStatusEnums.COMPLETED.getCode().equals(orderInfo.getOrderStatus())) {
            if (StringUtils.isEmpty(memoDTO.getMemo())) {
                logger.info("订单备注为空，不更新卖家备注");
                return false;
            }
            infoMapper.addOrderInfoSellerMemoByOrderId(memoDTO.getOrderId(), memoDTO.getMemo());
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmOrderInfoList(List<Long> orderIdList) {
        List<OrderFormInfo> infoList = infoMapper.selectAllByOrderIdList(orderIdList);
        infoList = infoList.stream().filter(order -> OrderStatusEnums.BE_CONFIRM.getCode().equals(order.getOrderStatus())).collect(Collectors.toList());
        List<Long> confirmOrderIdList = infoList.stream().map(OrderFormInfo::getOrderId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(confirmOrderIdList)) {
            infoMapper.batchConfirmOrderInfo(confirmOrderIdList);
            logService.insertBatchOrderLog("确认订单" , confirmOrderIdList , AdminHolderInfo.getAdminName());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult deliverOrderInfoList(List<Long> orderIdList) {
        JsonResult jsonResult = new JsonResult();
        Map<String, Object> returnMap = new HashMap<>();
        List<OrderFormInfo> infoList = infoMapper.selectAllByOrderIdList(orderIdList);
        List<OrderFormInfo> canDeliverInfoList = infoList.stream().filter(order -> OrderStatusEnums.CONFIRM.getCode().equals(order.getOrderStatus()) && DeliverStatusEnums.BE_DELIVER.getCode().equals(order.getDeliverStatus())).collect(Collectors.toList());
        infoList.removeAll(canDeliverInfoList);
        if (CollectionUtils.isNotEmpty(canDeliverInfoList)) {
            // 调用生成物流单方法
            List<Long> canDeliverOrderIdList = canDeliverInfoList.stream().map(OrderFormInfo::getOrderId).collect(Collectors.toList());
            logisticInfoService.createLogisticInfoBatch(canDeliverOrderIdList);
        }
        returnMap.put("successList", canDeliverInfoList);
        returnMap.put("failedList", infoList);
        return JsonResult.doSuccessful(returnMap);
    }

    @Override
    public List<OrderFormDetail> selectOrderDetailByOrderId(Long orderId) {
        OrderFormInfo orderInfo = infoMapper.selectOneByOrderId(orderId);
        if (orderInfo == null) {
            throw new ServiceException(OperationResultCode.ORDER_NOT_EXISTS);
        }
        return detailMapper.selectDetailByOrderId(orderId);
    }
}
